package com.example.gulimall.order.config;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;

@Configuration
public class MyRabbitConfig {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Bean
    public MessageConverter messageConverter(){
        return new Jackson2JsonMessageConverter();
    }

    // 定制RabbitTemplate
    @PostConstruct //创建完成后执行这个方法
    public void initRabbitTemplate(){
        // 设置确认回调 确认到达服务器
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            @Override
            public void confirm(CorrelationData correlationData, boolean b, String s) {
                // 1.消息的唯一id
                // 2.b是否成功收到
                // 3.原因

                // 一定要做好消息确认机制 做好手动ack
                // 每一个发送的消息一定要做好记录 定期将失败的消息再来发送
                //
            }
        });
        // 设置正确抵达队列 此函数等失败才会回调
        rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
            @Override
            public void returnedMessage(Message message, int i, String s, String s1, String s2) {
                // 只要没有投递就会回调
                // 1.投递失败的消息
                // 2.状态码
                // 3.回复的文本内容
                // 4.交换机
                // 5.路由键

                //来到这里说明报错误了 需要修改数据库当前消息的状态
            }
        });
        // 消费端确认 保证每个消息被正确消费 broker才可以删除
        // 1. 默认是自动确认的 只要消息接收到 服务端就会删除
        // 问题：收到很多消息 但只有一个成功被处理 然后就宕机了 发生消息丢失
        // 2. 手动情况下 如果不签收 就默认是unack
        // 3. 签收basicAck 拒签 basicReject(tag,是否批量签收,是否重新入队)
    }
}
